Verilog HDL中使用系统任务 $readmemh遇到问题及解决方法 您所在的位置:网站首页 finish class怎么读 Verilog HDL中使用系统任务 $readmemh遇到问题及解决方法

Verilog HDL中使用系统任务 $readmemh遇到问题及解决方法

#Verilog HDL中使用系统任务 $readmemh遇到问题及解决方法| 来源: 网络整理| 查看: 265

       在Verilog HDL程序中有两个系统任务$readmemb和$readmemh,用来从文件中读取数据到存贮器中。这两个系统任务可以在仿真的任何时刻被执行使用,其使用格式共有以下六种:

1) $readmemb("",);

2) $readmemb("",,);

3) $readmemb("",,,);

4) $readmemh("",);

5) $readmemh("",,);

6) $readmemh("",,,);

这两个系统任务看起来比较简单,但是在实际使用时还出现了不少问题,现在就将出现的问题及解决方法总结一下。

       这次实验的目的是将数字0---1023存储在一个记事本中,然后使用$readmemh将这1024个数据读取到存储器中,然后根据输入端口地址将数据通过输出端口输出。首先新建一个记事本,将数字0---1023添加到记事本中,由于读取文件任务只能通过二进制或者十六进制的方式读取,为了方便操作,就用十六进制的方式操作,将0---1023对应的十六进制数写在记事本中,每个数据占一行,用回车换行符区分数据。

        如何一次性生成0--1023的十六进制数呢?可以用excel表格来实现,具体操作方法详见上一篇文章 利用excel表格进行数据进制转换,将生成的数据复制到记事本中,记事本命名为num.txt。

下面新建一个工程,将num.txt记事本放在工程myrom文件中。

编写顶层文件

输入端口为时钟信号和数据地址信号,输出端口为ROM中数据输出。由于数据最大为1023,所以数据宽度设置为10位。

然后用$readmemh 任务将num.txt记事本中的内容读取到rom寄存器中,rom设置为1024个地址,每个地址的宽度为10位。下来在每个时钟的上升沿根据输入端口的地址输出rom中的数据。

下面编写测试代码

在一个循环中让地址addr的值从0一直增加到1023,这样顶层文件就会输出从0到1023地址中存储的数据了。注意在测试文件for循环中递增地址的值时,一定要延时一个时钟周期,因为顶层文件是在每个时钟上升沿才会读取一次数据,如果for循环中没有延时,顶层文件就读取不到正确的数据。

下面分析和综合一下编写好的代码

直接出现了七百多个警告,而且都是同一个原因引起的。双击第一条警告,跳转到报错位置。

从100开始有警告,前面的数据都正常,应该是十六进制的100系统默认为数据宽度是12位的,而代码中数据宽度设置的是10位的。所以系统提示数据位宽不匹配。

由于这里最大值时1023,没有超过10位,所以警告暂时不理它。直接仿真波形查看结果

输出的波形和打印的数据符合预期的结果,地址从0到1023,数据从0x000到0x3FF。正常情况下数据输出一次之后就应该结束,停止仿真。但是实际上从打印的数据和波形来看,当地址到1023又变成了0,for循环又继续执行,这样一直循环,导致仿真不会自动停止。这是为什么呢?看看测试文件哪里有问题。

对测试文件分析,感觉可能是地址控制出了问题,for循环的结束条件为:add



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有